#pragma once 

#include <optional>
#include <functional>
#include <system_error>

namespace helper {
namespace sqlite {
namespace stream {

template<typename T>
class Iterator  {
  public:
    typedef T Item;
    virtual ~Iterator(){}

    std::error_code foreach(const std::function<std::error_code(Item&)> & f){
      for(auto && o = next(); o; o = next()){
        if(auto && ec = f(o.value()); ec){
          return ec;
        }
      }
      return std::error_code();
    }
    size_t count() const {
      size_t count = 0;
      for(auto && o = const_cast<Iterator*>(this)->next(); o; o = const_cast<Iterator*>(this)->next(), ++count) 
        ;
      return count;
    }

    virtual std::optional<Item> next() = 0;
};

}//namespace stream
}//namespace sqlite
}//namespace helper
